Como tracear un archivo a traves de commits para saber de donde vino.
En nuestro proyecto tenemos un archivo project/sonar-project.properties que está en la rama main, en la rama staging, pero no en la rama develop, así que queremos ver como ha llegado a cada uno de estos sitios
Primero nos ponemos en la rama main y ejecutamos el siguiente comando:
git log --name-status -- project/sonar-project.properties
Aqui se nos muestra el commit en el que se ha creado el archivo, se deberían de mostrar todos los commits donde se ha modificado el archivo, pero por lo visto el archivo solo se ha modificado en su creación y por lo tanto solo sale un commit
Podemos profundizar un poco mas con el siguiente comando:
git log --name-status --follow -- project/sonar-project.properties
Como podemos ver al usar la opcion --follow el archivo no se creo en el commit que se nos mostraba antes, se había creado antes en otro commit, pero en ese commit se creó una copia del archivo que es la que se marca como creación del archivo en el primer commit.
NOTA: C100 indica archivo copiado, el 100 indica el porcentaje de lineas que se copiaron, en este caso el archivo completo
Ahora ejecutamos el siguiente comando para ver exactamente de que rama es el commit donde se creó/copió el archivo
git name-rev 2d733bc70528216814ffcd5b88beb0c76ff9547f
El comando nos indica que ese commit está referenciado a la rama lfv/sonarqube_integration 8 commits por detras de su HEAD:
lfv/sonarqube_integration~8
Lo que nos interesa saber es en que momento llegó ese archivo a la rama main lo miramos tal que así:
git log --first-parent --name-status -- project/sonar-project.properties
Con ese comando podemos ver que el commit que introdujo el archivo en la rama es b9ef083 que justo proviene de la rama en la que se creó el archivo, lfv/sonarqube_integration
, ademas podemos ver que el archivo se borró en un commit posterior y que se volvio a crear en un nuevo commit.Si nos vamos a la rama staging podemos repetir el proceso:
git log --first-parent --name-status -- project/sonar-project.properties
Aqui vemos que el archivo se mete en la rama staging a traves de un merge que se hace desde main
El archivo solo aparece como creado y con la opción --first-parent no vemos ninguna otra interacción, por lo tanto el archivo nunca se modifica ni borra, mas adelante vemos que si hay situaciones potenciales de borrar el archivo aunque no se llegue a hacer
si queremos indagar un poco mas acerca del commit en el que se introduce el archivo en staging podemos ejecutar el siguiente comando:
git log --name-status -m --full-history --graph -- project/sonar-project.properties
En está salida podemos ver el gráfico de todas las ramas y como se van mergeando, podemos ver el merge que introduce el archivo en la rama main (La felcha roja mas abajo del todo), el merge que introduce el archivo en staging (La flecha roja de el medio), y la flecha roja que está arriba marca un merge de main a develop, que probablemente introduzca el archivo en la rama develop, eso lo veremos a continuación
Si nos vamos a develop y ejecutamos este comando, vemos lo siguiente:
git log --first-parent --name-status -- project/sonar-project.properties
El archivo se crea en la rama que habíamos visto antes c1224bb y se borra en una rama mas adelante 4f6ff23 este es el motivo por el que el fichero project/sonar-project.properties está en las ramas main y staging pero no en develop, el archivo se metio en la rama, pero se borró a posteriori,
La pregunta ahora es, porque el archivo sigue estando en las ramas staging y main? si el flujo de merges es develop>staging>main
Si seguimos el commit en el que se borra el archivo podemos descubrir que es lo que pasa:
Ejecutamos el siguiente comando:
git log --name-status -m --full-history --all -- project/sonar-project.properties
NOTA: usamos la opcion --all para que se muestren todas las ramas por si el commit lleva a un merge con otra rama
y usamos el comando ""/" para buscar el commit 4f6ff2307c43e0cd617f31b495b51e413ca3c09f
La busqueda nos lleva a un nuevo merge
git name-rev f1f8d991d577198dcdb85becc71dbf1587004364
Es el merge con la rama de staging
NOTA: a veces en vez de usar name-rev podemos usar git branch --contains <id commit> y nos dará información mas amplia de que ramas contienen ese commit
Ahora tenemos que indagar por que el archivo project/sonar-project.properties no se borra cuando develop se mergea con staging.
si hacemos un show de la rama f1f8d99 vemos lo siguiente:
Como se puede ver el archivo project/sonar-project.properties no se borra, se marca como añadido porque una de las ramas lo borra y la otra lo mantiene, entonces el resultado con respecto a una de las ramas es que se añade, aún así tenemos que investigar que rama añade el archivo y cual lo borra, y por qué se decide mantener el archivo y no borrarlo
Vamos a investigar las dos ramas que forman parte del merge:
Si miramos la rama 7e6b672 vemos que el archivo está añadido:
y si miramos la rama 4f6ff23 vemos que el archivo está borrado:
Si miramos a las fechas de los dos commits vemos lo siguiente:
El commit que borra el archivo 4f6ff23 (16 Febrero) es mas reciente que el commit que lo mantiene 7e6b672 (11 Febrero), por lo tanto debería de prevalecer el borrado del archivo al hacer el merge.
Lo que ocurre aqui es un fallo de github, si en ese merge lo hacemos directamente con git el archivo queda borrado en el merge, pero desde github al hacer la PR y mergear prevalece el cambio del otro commit, ESTE FALLO ESTA DOCUMENTADO AQUI
Si no se diese ese problema, el cambio de develop (el borrado del archivo) se propagaría a las demas ramas, dejando el archivo borrado en todas las ramas
Git | Escenario